home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / ODF Release 3 / ODFDev / Draw / Sources / DrawSel.cpp < prev    next >
Encoding:
Text File  |  1996-12-16  |  30.6 KB  |  1,091 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                DrawSel.cpp
  4. //    Release Version:    $ ODF 3 $
  5. //
  6. //    Author:                Henri Lamiraux
  7. //
  8. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //========================================================================================
  11.  
  12. #include "ODFDraw.hpp"
  13.  
  14. #ifndef DRAWSEL_H
  15. #include "DrawSel.h"
  16. #endif
  17.  
  18. #ifndef DRAWCONT_H
  19. #include "DrawCont.h"
  20. #endif
  21.  
  22. #ifndef DRAWFRM_H
  23. #include "DrawFrm.h"
  24. #endif
  25.  
  26. #ifndef DRAWPART_H
  27. #include "DrawPart.h"
  28. #endif
  29.  
  30. #ifndef BASESHP_H
  31. #include "BaseShp.h"
  32. #endif
  33.  
  34. #ifndef BOUNDSHP_H
  35. #include "BoundShp.h"
  36. #endif
  37.  
  38. #ifndef LINESHP_H
  39. #include "LineShp.h"
  40. #endif
  41.  
  42. #ifndef OVALSHP_H
  43. #include "OvalShp.h"
  44. #endif
  45.  
  46. #ifndef RECTSHP_H
  47. #include "RectShp.h"
  48. #endif
  49.  
  50. #ifndef RRECTSHP_H
  51. #include "RRectShp.h"
  52. #endif
  53.  
  54. #ifndef TEXTSHP_H
  55. #include "TextShp.h"
  56. #endif
  57.  
  58. #ifndef DRAWCLIP_H
  59. #include "DrawClip.h"
  60. #endif
  61.  
  62. #ifndef DRAWPRXY_H
  63. #include "DrawPrxy.h"
  64. #endif
  65.  
  66. #ifndef UTILS_H
  67. #include "Utils.h"
  68. #endif
  69.  
  70. #ifndef SHPTRAKR_H
  71. #include "ShpTrakr.h"
  72. #endif
  73.  
  74. #ifndef DRAWCMDS_H
  75. #include "DrawCmds.h"
  76. #endif
  77.  
  78. #ifndef DRAWLINK_H
  79. #include "DrawLink.h"
  80. #endif
  81.  
  82. #ifndef DRWPRMSE_H
  83. #include "DrwPrmse.h"
  84. #endif
  85.  
  86. #ifndef GROUPSHP_H
  87. #include "GroupShp.h"
  88. #endif
  89.  
  90. // ----- Part Layer -----
  91.  
  92. #ifndef FWCONTXT_H
  93. #include "FWContxt.h"
  94. #endif
  95.  
  96. #ifndef FWSESION_H
  97. #include "FWSesion.h"
  98. #endif
  99.  
  100. #ifndef FWITERS_H
  101. #include "FWIters.h"
  102. #endif
  103.  
  104. #ifndef FWUTIL_H
  105. #include "FWUtil.h"
  106. #endif
  107.  
  108. #ifndef FWPRESEN_H
  109. #include "FWPresen.h"
  110. #endif
  111.  
  112. #ifndef FWKIND_H
  113. #include "FWKind.h"
  114. #endif
  115.  
  116. // ----- OS Layer -----
  117.  
  118. #ifndef FWORDCOL_H
  119. #include "FWOrdCol.h"
  120. #endif
  121.  
  122. #ifndef FWSUSINK_H
  123. #include "FWSUSink.h"
  124. #endif
  125.  
  126. #ifndef FWODGEOM_H
  127. #include "FWODGeom.h"
  128. #endif
  129.  
  130. #ifndef FWEVENT_H
  131. #include "FWEvent.h"
  132. #endif
  133.  
  134. #ifndef SLMixOS_H
  135. #include "SLMixOS.h"
  136. #endif
  137.  
  138. // ----- Foundation Includes -----
  139.  
  140. #ifndef FWSTREAM_H
  141. #include "FWStream.h"
  142. #endif
  143.  
  144. #ifndef FWSOMENV_H
  145. #include "FWSOMEnv.h"
  146. #endif
  147.  
  148. // ----- OpenDoc Includes -----
  149.  
  150. #ifndef SOM_ODShape_xh
  151. #include <Shape.xh>
  152. #endif
  153.  
  154. #ifndef SOM_ODStorageUnit_xh
  155. #include <StorageU.xh>
  156. #endif
  157.  
  158. #ifndef SOM_Module_OpenDoc_StdProps_defined
  159. #include <StdProps.xh>
  160. #endif
  161.  
  162. #ifndef SOM_ODSession_xh
  163. #include <ODSessn.xh>
  164. #endif
  165.  
  166. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  167. #include <StdTypes.xh>
  168. #endif
  169.  
  170. #ifdef __MRC__
  171. // This is to go around a bug in MRC. It doesn't seems to see the extern
  172. // in DrawLink.cpp
  173. FW_DEFINE_AUTO_TEMPLATE(FW_TOrderedCollection, CDrawPublishLink)
  174. #endif
  175.  
  176. //========================================================================================
  177. //    Segmentation
  178. //========================================================================================
  179.  
  180. #ifdef FW_BUILD_MAC
  181. #pragma segment odfdraw2
  182. #endif
  183.  
  184. //========================================================================================
  185. //    class CDrawSelection
  186. //========================================================================================
  187.  
  188. FW_DEFINE_AUTO(CDrawSelection)
  189.     
  190. //----------------------------------------------------------------------------------------
  191. //    CDrawSelection::CDrawSelection
  192. //----------------------------------------------------------------------------------------
  193.  
  194. CDrawSelection::CDrawSelection(Environment* ev, CDrawPart* drawPart):
  195.     FW_CSelection(ev, TRUE, TRUE),
  196.     fDrawPart(drawPart),
  197.     fUpdateShape(NULL),
  198.     fFrozenCount(0),
  199.     fCount(0),
  200.     fSelectionContent(NULL),
  201.     fWorkingHandle(FW_kZeroRect, FW_kFill),
  202.     fDraggedContent(NULL)
  203. {
  204.     fSelectionContent = FW_NEW(CDrawSelectionContent, (ev, drawPart, this));
  205.     fWorkingHandle.SetInk(FW_kInvertInk);
  206.     FW_END_CONSTRUCTOR
  207. }
  208.  
  209. //----------------------------------------------------------------------------------------
  210. //    CDrawSelection::~CDrawSelection
  211. //----------------------------------------------------------------------------------------
  212.  
  213. CDrawSelection::~CDrawSelection()
  214. {
  215.     FW_START_DESTRUCTOR
  216.     
  217.     if (fUpdateShape)
  218.     {
  219.         FW_SOMEnvironment ev;
  220.         fUpdateShape->Release(ev);
  221.     }
  222.     
  223.     delete fSelectionContent;
  224. }
  225.  
  226. //----------------------------------------------------------------------------------------
  227. //    CDrawSelection::GetSelectedContent
  228. //----------------------------------------------------------------------------------------
  229.  
  230. FW_CContent* CDrawSelection::GetSelectedContent(Environment* ev)
  231. {
  232. FW_UNUSED(ev);
  233.     return fSelectionContent;
  234. }
  235.  
  236. //----------------------------------------------------------------------------------------
  237. //    CDrawSelection::WhichHandle
  238. //----------------------------------------------------------------------------------------
  239.  
  240. CBaseShape* CDrawSelection::WhichHandle(Environment* ev, FW_CGraphicContext& gc, const FW_CPoint& mouse, short& whichHandle, FW_Fixed zoomFactor) const
  241. {
  242. FW_UNUSED(ev);
  243.     whichHandle = 0;
  244.     
  245.     if (fCount != 0)
  246.     {
  247.         CDrawContentShapeIterator ite(fSelectionContent);
  248.         for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  249.         {
  250.             whichHandle = shape->WhichHandle(gc, mouse, zoomFactor);
  251.             if (whichHandle != 0)
  252.                 return shape;
  253.         }
  254.     }
  255.     
  256.     return NULL;
  257. }
  258.  
  259. //----------------------------------------------------------------------------------------
  260. //    CDrawSelection::RenderSelectionHandles
  261. //----------------------------------------------------------------------------------------
  262.  
  263. void CDrawSelection::RenderSelectionHandles(Environment* ev, FW_CGraphicContext& gc, FW_Fixed zoomFactor)
  264. {
  265. FW_UNUSED(ev);
  266.     CDrawContentShapeIterator ite(fSelectionContent);
  267.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  268.     {
  269.         shape->RenderHandles(gc, zoomFactor);    
  270.     }
  271. }
  272.  
  273. //----------------------------------------------------------------------------------------
  274. //    CDrawSelection::InvalidateSelectionHandles
  275. //----------------------------------------------------------------------------------------
  276.  
  277. void CDrawSelection::InvalidateSelectionHandles(Environment* ev, CDrawFrame* frame)
  278. {    
  279.     FW_CSuperView* contentView = frame->GetContentView(ev);
  280.     FW_CAcquiredODShape workingShape = FW_NewODShape(ev);
  281.     FW_Fixed penSize = CalcHandlePenSize(frame->GetZoomFactor());
  282.     
  283.     CDrawContentShapeIterator ite(fSelectionContent);
  284.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  285.     {
  286.         shape->InvalidateHandles(ev, contentView, workingShape, penSize);
  287.     }
  288. }
  289.  
  290. //----------------------------------------------------------------------------------------
  291. //    CDrawSelection::RenderAllHandles
  292. //----------------------------------------------------------------------------------------
  293.  
  294. void CDrawSelection::RenderAllHandles(Environment* ev, CDrawFrame* frame)
  295. {
  296.     if (fCount != 0)
  297.     {        
  298.         FW_CFrameFacetIterator ite(ev, frame);
  299.         for (ODFacet* facet = (ODFacet*)ite.First(ev); ite.IsNotComplete(ev); facet = (ODFacet*)ite.Next(ev))
  300.         {
  301.             FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
  302.             RenderSelectionHandles(ev, vc, frame->GetZoomFactor());
  303.         }
  304.     }
  305. }
  306.  
  307. //----------------------------------------------------------------------------------------
  308. //    CDrawSelection::RenderHandles
  309. //----------------------------------------------------------------------------------------
  310.  
  311. void CDrawSelection::RenderHandles(Environment* ev, CBaseShape* shape)
  312. {
  313.     FW_CPresentationFrameIterator ite(ev, GetPresentation(ev));
  314.     for (CDrawFrame* frame = (CDrawFrame*)ite.First(ev); ite.IsNotComplete(ev); frame = (CDrawFrame*)ite.Next(ev))
  315.     {
  316.         if (frame->HasSelectionFocus(ev))
  317.         {
  318.             // ODFrame::SetInLimbo(true) can trigger this, on a detached frame, which has no window!
  319.             FW_CWindow* window = frame->GetWindow(ev);
  320.             if (window && window->IsActive(ev))
  321.             {
  322.                 FW_CFrameFacetIterator i(ev, frame);            
  323.                 for (ODFacet* facet = i.First(ev); i.IsNotComplete(ev); facet = i.Next(ev))
  324.                 {
  325.                     FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
  326.                     shape->RenderHandles(vc, frame->GetZoomFactor());
  327.                 }
  328.             }
  329.         }
  330.     }
  331. }
  332.  
  333. //----------------------------------------------------------------------------------------
  334. //    CDrawSelection::CloseSelection
  335. //----------------------------------------------------------------------------------------
  336.  
  337. void CDrawSelection::CloseSelection(Environment* ev)
  338. {
  339.     CBaseShape* shape;
  340.     while ((shape = fSelectionContent->GetFirstShape()) != NULL)
  341.     {
  342.         DoRemove(ev, shape);
  343.         RenderHandles(ev, shape);        // turn off
  344.     }
  345.  
  346.     CalcCache(ev);
  347. }
  348.  
  349. //----------------------------------------------------------------------------------------
  350. //    CDrawSelection::AddToSelection
  351. //----------------------------------------------------------------------------------------
  352.  
  353. void CDrawSelection::AddToSelection(Environment* ev, CBaseShape* theShape, FW_Boolean renderHandles)
  354. {                
  355.     if (theShape != NULL)
  356.     {
  357.         fDrawPart->SetTool(ev, kSelectTool);
  358.         DoAdd(ev, theShape);
  359.         if (renderHandles)
  360.             RenderHandles(ev, theShape);    // Turn on    
  361.     }        
  362.             
  363.     CalcCache(ev);
  364. }
  365.  
  366. //----------------------------------------------------------------------------------------
  367. //    CDrawSelection::RemoveFromSelection
  368. //----------------------------------------------------------------------------------------
  369.  
  370. void CDrawSelection::RemoveFromSelection(Environment* ev, CBaseShape* shape, FW_Boolean renderHandles)
  371. {                
  372.     if (shape != NULL)
  373.     {
  374.         DoRemove(ev, shape);
  375.         if (renderHandles)
  376.             RenderHandles(ev, shape);        // Turn Off
  377.     }    
  378.     
  379.     CalcCache(ev);
  380. }
  381.  
  382. //----------------------------------------------------------------------------------------
  383. //    CDrawSelection::DoAdd
  384. //----------------------------------------------------------------------------------------
  385.  
  386. void CDrawSelection::DoAdd(Environment* ev, CBaseShape *shape)
  387. {
  388.     fSelectionContent->AddShape(ev, shape);
  389.     this->ShapeAdded(ev, shape);
  390. }
  391.  
  392. //----------------------------------------------------------------------------------------
  393. //    CDrawSelection::ShapeAdded
  394. //----------------------------------------------------------------------------------------
  395. void CDrawSelection::ShapeAdded(Environment* ev, CBaseShape* shape)
  396. {
  397.     shape->SelectShape(ev, true);
  398.     fCount++;
  399.     if (shape->IsFrozen())
  400.         fFrozenCount++;
  401. }
  402.  
  403. //----------------------------------------------------------------------------------------
  404. //    CDrawSelection::DoRemove
  405. //----------------------------------------------------------------------------------------
  406.  
  407. void CDrawSelection::DoRemove(Environment* ev, CBaseShape *shape)
  408. {
  409.     fSelectionContent->RemoveShape(ev, shape);
  410.     shape->SelectShape(ev, false);
  411.     fCount--;
  412.     if (shape->IsFrozen())
  413.         fFrozenCount--;
  414. }
  415.  
  416. //----------------------------------------------------------------------------------------
  417. //    CDrawSelection::ClearSelection
  418. //----------------------------------------------------------------------------------------
  419.  
  420. void CDrawSelection::ClearSelection(Environment* ev)
  421. {
  422.     // There's no easy way to find out if the content being cleared is part of
  423.     // a pending clipboard link, so we have to clear that just in case. This will
  424.     // prevent the user attemping to make a link to content that was removed.
  425.     // It also prevents a pending link from being the last reference to removed content
  426.     // when ReleaseAll is called, thus triggering a call to ODFrame::Removed at a bad time
  427.     
  428.     // The alternative:  Get the pending link, and search its content for each of the selected
  429.     // shapes.  Not unthinkable, just no time for that right now.
  430.     
  431.     fDrawPart->GetLinkManager(ev)->DeletePendingClipboardLink(ev);
  432.     
  433.     CBaseShape *shape;
  434.     while ((shape = fSelectionContent->GetFirstShape()) != NULL)
  435.     {
  436.         DoRemove(ev, shape);                // Remove from selection list
  437.         fDrawPart->RemoveShapeFromPart(ev, shape);    // Remove from part
  438.     }
  439.     
  440.     CDrawFacetClipper facetClipper(fDrawPart);
  441.     facetClipper.Clip(ev, GetPresentation(ev), fUpdateShape);
  442.     GetPresentation(ev)->Invalidate(ev, fUpdateShape);
  443.     
  444.     CalcCache(ev);
  445. }
  446.  
  447. //----------------------------------------------------------------------------------------
  448. //    CDrawSelection::SelectAll
  449. //----------------------------------------------------------------------------------------
  450.  
  451. void CDrawSelection::SelectAll(Environment* ev)
  452. {    
  453.     CDrawFrame* activeFrame = (CDrawFrame*)fDrawPart->GetLastActiveFrame(ev);
  454.     
  455.     RenderAllHandles(ev, activeFrame);
  456.  
  457.     CDrawContentShapeIterator ite(fDrawPart->GetDrawContent());
  458.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  459.     {
  460.         if (!shape->IsSelectedShape())
  461.             DoAdd(ev, shape);
  462.     }
  463.     
  464.     RenderAllHandles(ev, activeFrame);
  465.  
  466.     CalcCache(ev);
  467.     
  468.     fDrawPart->SetTool(ev, kSelectTool);
  469. }
  470.  
  471. //----------------------------------------------------------------------------------------
  472. //    CDrawSelection::IsEmpty
  473. //----------------------------------------------------------------------------------------
  474.  
  475. FW_Boolean CDrawSelection::IsEmpty(Environment* ev) const
  476. {    
  477. FW_UNUSED(ev);
  478.     return fCount == 0;
  479. }
  480.  
  481. //----------------------------------------------------------------------------------------
  482. //    CDrawSelection::CenterSelection
  483. //----------------------------------------------------------------------------------------
  484.  
  485. FW_CPoint CDrawSelection::CenterSelection(Environment* ev, FW_CFrame* scopeFrame)
  486. {
  487.     FW_ASSERT(scopeFrame);
  488.     
  489.     fDrawPart->SetTool(ev, kSelectTool);
  490.  
  491.     CalcCache(ev);
  492.     
  493.     FW_CRect bounds = scopeFrame->GetContentView(ev)->GetBoundsInContent(ev);
  494.     FW_CRect box(fDragRect);
  495.     box.PlaceInCenterOf(bounds);
  496.             
  497.     FW_CPoint result(box.left - fDragRect.left, box.top - fDragRect.top);
  498.     OffsetSelection(ev, result.x, result.y);
  499.     
  500.     CDrawFacetClipper facetClipper(fDrawPart);
  501.     facetClipper.Clip(ev, GetPresentation(ev), fUpdateShape);    
  502.     GetPresentation(ev)->Invalidate(ev, fUpdateShape);
  503.  
  504.     return result;
  505. }
  506.  
  507. //----------------------------------------------------------------------------------------
  508. //    CDrawSelection::Resize
  509. //----------------------------------------------------------------------------------------
  510.  
  511. FW_Boolean CDrawSelection::Resize(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  512. {    
  513.     if (fClickedHandle == 0)
  514.         return FALSE;
  515.  
  516.     if (fDrawPart->IsReadOnly(ev))    // can't resize read only part
  517.         return TRUE;
  518.  
  519.     if (!theMouseEvent.WaitUntilMouseMoved(ev))
  520.         return TRUE;
  521.     
  522.     ODFacet* facet = theMouseEvent.GetFacet(ev);
  523.     CDrawFrame *frame = (CDrawFrame*)FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
  524.  
  525.     CBaseShape* anchorShape = GetAnchorShape();
  526.     
  527.     FW_CInk resizeInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  528.     FW_CStyle resizeStyle(anchorShape->GetResizeStyle());
  529.     
  530.     CResizeTracker resizeTracker(ev, frame->GetContentView(ev), facet, anchorShape, fClickedHandle, resizeInk, resizeStyle, TRUE);
  531.     if (resizeTracker.Track(ev, theMouseEvent))
  532.     {
  533.         GetPresentation(ev)->Invalidate(ev, fUpdateShape);
  534.  
  535.         FW_CPoint lastLocation;
  536.         resizeTracker.GetLastLocation(lastLocation);
  537.         FW_CRect srcRect, dstRect;
  538.         anchorShape->GetMapRects(fClickedHandle, lastLocation, srcRect, dstRect);
  539.  
  540.         CResizeShapeCommand* cmd = FW_NEW(CResizeShapeCommand,
  541.                                             (ev, fDrawPart, frame, this,
  542.                                              srcRect, dstRect));
  543.         cmd->Execute(ev);
  544.     }
  545.     else
  546.     {
  547.         FW_CViewContext vc(ev, frame->GetContentView(ev), facet);
  548.         
  549.         FW_Fixed penSize = CalcHandlePenSize(frame->GetZoomFactor());
  550.         anchorShape->CalcHandle(fClickedHandle, &fWorkingHandle, penSize);
  551.         fWorkingHandle.Render(vc);    // redraw the handle
  552.     }
  553.     
  554.     return TRUE;
  555. }
  556.  
  557. //----------------------------------------------------------------------------------------
  558. //    CDrawSelection::CalcCache
  559. //----------------------------------------------------------------------------------------
  560.  
  561. void CDrawSelection::CalcCache(Environment* ev)
  562. {
  563.     fDragRect.Clear();
  564.     
  565.     if (fUpdateShape == NULL)
  566.         fUpdateShape = ::FW_NewODShape(ev);
  567.     
  568.     if (fCount == 0)
  569.         return;
  570.     
  571.     FW_CAcquiredODShape aqTempShape = ::FW_NewODShape(ev);
  572.     FW_CRect tempRect;
  573.  
  574.     FW_Boolean first = TRUE;
  575.     CDrawContentShapeIterator ite(fSelectionContent);
  576.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  577.     {
  578.         shape->GetDragRect(tempRect);
  579.         shape->GetUpdateBox(ev, aqTempShape);
  580.         if (first)
  581.         {
  582.             fDragRect = tempRect;
  583.             fUpdateShape->CopyFrom(ev, aqTempShape);
  584.         }
  585.         else
  586.         {
  587.             fDragRect |= tempRect;
  588.             fUpdateShape->Union(ev, aqTempShape);
  589.         }
  590.                         
  591.         first = FALSE;
  592.     }
  593.     
  594. }
  595.  
  596. //----------------------------------------------------------------------------------------
  597. //    CDrawSelection::AcquireSelectionShape
  598. //----------------------------------------------------------------------------------------
  599.  
  600. ODShape* CDrawSelection::AcquireSelectionShape(Environment* ev, ODFacet* facet, FW_CFrame* frame)
  601. {
  602. FW_UNUSED(frame);
  603. FW_UNUSED(facet);
  604.  
  605.     return ::FW_NewODShape(ev, fDragRect);
  606. }
  607.  
  608. //----------------------------------------------------------------------------------------
  609. //    CDrawSelection::AcquireSelectionOutline
  610. //----------------------------------------------------------------------------------------
  611.  
  612. ODShape* CDrawSelection::AcquireSelectionOutline(Environment* ev, ODFacet* facet, FW_CFrame* frame)
  613. {
  614.     FW_CAcquiredODShape outline;
  615.     
  616.     if (GetAnchorShape() == NULL)
  617.         outline = FW_CopyAndRelease(ev, AcquireSelectionShape(ev, facet, frame));
  618.     else
  619.         outline = GetAnchorShape()->CreateShapeOutline(ev);
  620.  
  621.     if (fCount > 1)
  622.     {
  623.         FW_CAcquiredODShape shapeOutline = FW_CSelection::AcquireSelectionOutline(ev, facet, frame);
  624.         outline->Union(ev, shapeOutline);
  625.     }
  626.  
  627.     return outline.Orphan();
  628. }
  629.  
  630. //----------------------------------------------------------------------------------------
  631. //    CDrawSelection::OffsetSelection
  632. //----------------------------------------------------------------------------------------
  633.  
  634. void CDrawSelection::OffsetSelection(Environment* ev, FW_Fixed xDelta, FW_Fixed yDelta)
  635. {
  636.     FW_CAcquiredODShape aqUnionShape(fUpdateShape->Copy(ev));
  637.     
  638.     CDrawContentShapeIterator ite(fSelectionContent);
  639.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  640.     {
  641.         shape->OffsetShape(ev, xDelta, yDelta);
  642.     }
  643.     
  644.     CalcCache(ev);
  645.  
  646.     aqUnionShape->Union(ev, fUpdateShape);
  647.     FW_CPresentation* thePresentation = GetPresentation(ev);
  648.     
  649.     FW_CPresentationFrameIterator ite2(ev, thePresentation);
  650.     for (CDrawFrame* frame = (CDrawFrame*)ite2.First(ev); ite2.IsNotComplete(ev); frame = (CDrawFrame*)ite2.Next(ev))
  651.     {
  652.         FW_CRect bounds = frame->GetContentView(ev)->GetBoundsInContent(ev);
  653.         CDrawContentShapeIterator ite(fSelectionContent);
  654.         for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  655.         {
  656.             shape->MakePurgeable(ev, frame, bounds);
  657.         }
  658.     }
  659.     
  660.     CDrawFacetClipper facetClipper(fDrawPart);
  661.     facetClipper.Clip(ev, thePresentation, aqUnionShape);
  662. }
  663.  
  664. //----------------------------------------------------------------------------------------
  665. //    CDrawSelection::SelectWithRectangle
  666. //----------------------------------------------------------------------------------------
  667.  
  668. void CDrawSelection::SelectWithRectangle(Environment* ev, const FW_CMouseEvent& theMouseEvent)
  669. {
  670.     // Now that shapes are refcounted, its probably a bad idea to make one on the stack.
  671.     // If we call its Release method, it will try to delete itself.  If we don't, then 
  672.     // the destructor will complain about the ref count not being 0.
  673.     
  674.     CRectShape* rectShape = FW_NEW(CRectShape, (fDrawPart));
  675.     
  676.     FW_TRY
  677.     {
  678.         FW_CStyle trackStyle(FW_kFixed0, FW_kAntPat);
  679.         FW_CInk trackInk(FW_kRGBBlack, FW_kRGBWhite, FW_kXOr);
  680.         rectShape->ChangeRenderVerb(ev, kFrameOnly);
  681.         rectShape->SetFrameInk(trackInk);
  682.         rectShape->SetFrameStyle(trackStyle);
  683.         
  684.         ODFacet* facet = theMouseEvent.GetFacet(ev);
  685.         FW_CFrame *frame = FW_CFrame::ODtoFWFrame(ev, facet->GetFrame(ev));
  686.     
  687.         CShapeTracker tracker(ev, frame->GetContentView(ev), facet, rectShape, FALSE);
  688.         if (tracker.Track(ev, theMouseEvent))
  689.         {
  690.             FW_Boolean isShift = theMouseEvent.IsExtendModifier(ev);
  691.             FW_CRect selectRect = rectShape->GetRectGeometry();
  692.             
  693.             CDrawContentShapeIterator ite(fDrawPart->GetDrawContent());
  694.             for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  695.             {
  696.                 if (shape->InSelectionRect(selectRect))
  697.                 {
  698.                     if (shape->IsSelectedShape())
  699.                     {
  700.                         if (isShift)
  701.                         {
  702.                             DoRemove(ev, shape);
  703.                             RenderHandles(ev, shape);        // Turn Off
  704.                         }
  705.                     }
  706.                     else
  707.                     {
  708.                         DoAdd(ev, shape);
  709.                         RenderHandles(ev, shape);    // Turn on    
  710.                     }
  711.                 }
  712.                 else if (shape->IsSelectedShape() && !isShift)
  713.                 {
  714.                     DoRemove(ev, shape);
  715.                     RenderHandles(ev, shape);        // Turn Off
  716.                 }
  717.             }            
  718.             CalcCache(ev);
  719.         }
  720.         else
  721.         {
  722.             if (!theMouseEvent.IsExtendModifier(ev))
  723.                 CloseSelection(ev);
  724.         }
  725.     }
  726.     FW_CATCH_BEGIN
  727.     FW_CATCH_EVERYTHING ()
  728.     {
  729.         rectShape->Release();
  730.         FW_THROW_SAME ();
  731.     }
  732.     FW_CATCH_END
  733.     
  734.     rectShape->Release();
  735.     
  736. }
  737.  
  738. //----------------------------------------------------------------------------------------
  739. //    CDrawSelection::SetFrozen
  740. //----------------------------------------------------------------------------------------
  741.  
  742. void CDrawSelection::SetFrozen(Environment* ev, FW_Boolean state)
  743. {
  744. FW_UNUSED(ev);
  745.     CDrawContentShapeIterator ite(fSelectionContent);
  746.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  747.     {
  748.         if (shape->SetFrozen(state))
  749.         {
  750.             state ? fFrozenCount++ : fFrozenCount--;
  751.         }
  752.     }
  753. }
  754.  
  755. //----------------------------------------------------------------------------------------
  756. //    CDrawSelection::SelectionChanged
  757. //----------------------------------------------------------------------------------------
  758.  
  759. void CDrawSelection::SelectionChanged(Environment* ev, ODUpdateID updateID)
  760. {
  761.     CDrawPublishLinkCollection temp;
  762.     
  763.     CDrawContentShapeIterator ite(fSelectionContent);
  764.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  765.     {
  766.         if (shape->IsPublished())
  767.         {
  768.             if (!temp.Contains(shape->GetPublishLink()))
  769.                 temp.AddLast(shape->GetPublishLink());
  770.         }
  771.     }
  772.     
  773.     CDrawPublishLinkCollectionIterator tempIte(&temp);
  774.     for (CDrawPublishLink* link = tempIte.First(); tempIte.IsNotComplete(); link = tempIte.Next())
  775.     {
  776.         link->ContentUpdated(ev, updateID);
  777.     }
  778.     
  779.     temp.RemoveAll();
  780. }
  781.  
  782. //----------------------------------------------------------------------------------------
  783. //    CDrawSelection::IsSelectionLinkable
  784. //----------------------------------------------------------------------------------------
  785. //    Don't write a link spec if any of the selected shapes is in a link destination
  786.  
  787. FW_Boolean CDrawSelection::IsSelectionLinkable(Environment* ev)
  788. {
  789.     // We can link a selection that is already one link source. Unfortunately
  790.     // the search will be repeated afterwards by the framework to see if a
  791.     // link already exists.  Perhaps IsSelectionLinkable could be combined with DoFindLinkSource
  792.     // so that parts can determine both linkability and existing link at once!
  793.     
  794.     if (this->DoFindLinkSource(ev) != NULL)
  795.         return TRUE;
  796.         
  797.     FW_Boolean result = TRUE;
  798.     
  799.     // This imposes ODFDraws peculiar limitations:  No source or dest content may
  800.     // be included in a link source:
  801.     
  802.     CDrawContentShapeIterator ite(fSelectionContent);
  803.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  804.     {
  805.         if (shape->IsInLinkDestination(ev))
  806.         {
  807.             result = FALSE;
  808.             break;
  809.         }
  810.         else if (shape->IsPublished())    // don't allow a shape to be published more than once
  811.         {
  812.             result = FALSE;
  813.             break;
  814.         }
  815.     }
  816.     
  817.     return result;
  818. }
  819.  
  820. //----------------------------------------------------------------------------------------
  821. //    CDrawSelection::CanPasteAsLink
  822. //----------------------------------------------------------------------------------------
  823. FW_Boolean CDrawSelection::CanPasteAsLink(Environment* ev, ODPasteAsMergeSetting& setting,
  824.                                           ODStorageUnit* su)
  825. {
  826.     // Check whether the storage unit contains mergeable content
  827.     if (su->Exists(ev, kODPropContents, fDrawPart->GetPartKind(ev)->GetType(ev), 0))
  828.     {
  829.         if (su->Exists(ev, kODPropContentFrame, kODWeakStorageUnitRef, 0))
  830.             setting = kODPasteAsEmbed;
  831.         else
  832.             setting = kODPasteAsMerge;
  833.     }
  834.     else    // foreign content - cannot be merged
  835.         setting = kODPasteAsEmbedOnly;
  836.     
  837.     return fAllowLink;
  838. }
  839.  
  840. //----------------------------------------------------------------------------------------
  841. //    CDrawSelection::IsMouseInDraggableItem
  842. //----------------------------------------------------------------------------------------
  843.  
  844. FW_Boolean CDrawSelection::IsMouseInDraggableItem(Environment* ev, FW_CFrame* frame, 
  845.                                                 const FW_CMouseEvent& theMouseEvent, 
  846.                                                 FW_Boolean inBackground)
  847. {    
  848.     fClickedHandle = 0;
  849.     fAnchorShape = NULL;
  850.  
  851.     if (!inBackground && fDrawPart->GetTool() != kSelectTool)
  852.         return FALSE;
  853.         
  854.     FW_CViewContext vc(ev, frame->GetContentView(ev), theMouseEvent.GetFacet(ev));
  855.  
  856.     // ----- Look first for a handle -----
  857.     FW_CPoint where = theMouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
  858.     frame->GetContentView(ev)->FrameToViewContent(ev, where);
  859.  
  860.     CBaseShape* clickedShape = WhichHandle(ev, vc, where, fClickedHandle, ((CDrawFrame*)frame)->GetZoomFactor());
  861.     if (clickedShape != NULL)
  862.     {
  863.         fAnchorShape = clickedShape;
  864.         return FALSE;            // if in a handle we won't drag
  865.     }
  866.     
  867.     // ----- then look for a selected shape -----
  868.     CBaseShape* shape = fDrawPart->WhichShape(ev, vc, theMouseEvent, TRUE);
  869.     
  870.     if (shape != NULL && shape->IsSelectedShape())
  871.     {
  872.         fAnchorShape = shape;
  873.         return TRUE;
  874.     }
  875.     
  876.     return FALSE;
  877. }
  878.  
  879. //----------------------------------------------------------------------------------------
  880. // CDrawSelection::UpdateSelectionOnMouseDown
  881. //----------------------------------------------------------------------------------------
  882.  
  883. void CDrawSelection::UpdateSelectionOnMouseDown(Environment* ev, 
  884.                                             const FW_CMouseEvent& mouseEvent,
  885.                                             ODFacet* embeddedFacet,
  886.                                             FW_Boolean inEmbeddedFrameBorder,
  887.                                             FW_Boolean inBackground)
  888. {
  889.     if (inEmbeddedFrameBorder)
  890.     {
  891.         fClickedHandle = 0;
  892.         fAnchorShape = NULL;
  893.  
  894.         CBaseShape *theShape = FW_DYNAMIC_CAST(CBaseShape, fDrawPart->GetProxy(ev, embeddedFacet->GetFrame(ev)));
  895.         FW_ASSERT(theShape);
  896.         
  897.         if (theShape->IsGrouped())
  898.             theShape = theShape->GetGroup();
  899.         
  900.         if (!theShape->IsSelectedShape())
  901.             AddToSelection(ev, theShape, TRUE);        
  902.         
  903.         fAnchorShape = theShape;
  904.     }
  905.     else if (fDrawPart->GetTool() == kSelectTool || inBackground)
  906.     {
  907.         FW_CFrame *frame = FW_CFrame::ODtoFWFrame(ev, mouseEvent.GetFacet(ev)->GetFrame(ev));
  908.         FW_CViewContext vc(ev, frame->GetContentView(ev), mouseEvent.GetFacet(ev));
  909.         
  910.         // ----- First look if we are in a resize handle -----
  911.         FW_CPoint where = mouseEvent.GetMousePosition(ev, FW_CMouseEvent::kFrame);
  912.         frame->GetContentView(ev)->FrameToViewContent(ev, where);
  913.     
  914.         short  clickedHandle;
  915.         if (WhichHandle(ev, vc, where, clickedHandle, ((CDrawFrame*)frame)->GetZoomFactor()) != NULL)
  916.             return;
  917.  
  918.         // ----- So now we are not in a handle -----
  919.         CBaseShape* clickedShape = fDrawPart->WhichShape(ev, vc, mouseEvent, FALSE);
  920.         if (clickedShape)
  921.         {
  922.             if (mouseEvent.IsExtendModifier(ev))
  923.             {
  924.                 if (clickedShape->IsSelectedShape())
  925.                 {
  926.                     RemoveFromSelection(ev, clickedShape, !inBackground);
  927.                     if (clickedShape == fAnchorShape)
  928.                         fAnchorShape = NULL;
  929.                 }
  930.                 else
  931.                 {
  932.                     AddToSelection(ev, clickedShape, !inBackground);
  933.                     fAnchorShape = clickedShape;
  934.                 }
  935.             }
  936.             else if (!clickedShape->IsSelectedShape())
  937.             {
  938.                 fAnchorShape = clickedShape;
  939.                 CloseSelection(ev);
  940.                 AddToSelection(ev, clickedShape, !inBackground);
  941.             }    
  942.         }
  943.     }
  944. }
  945.  
  946. //----------------------------------------------------------------------------------------
  947. //    CDrawSelection::DeleteSelection
  948. //----------------------------------------------------------------------------------------
  949. void CDrawSelection::DeleteSelection(Environment* ev)
  950. {
  951.     CBaseShape *shape;
  952.     while ((shape = fSelectionContent->GetFirstShape()) != NULL)
  953.     {
  954.         DoRemove(ev, shape);                        // Remove from selection
  955.         fDrawPart->RemoveShapeFromPart(ev, shape);    // Remove from part
  956.     }
  957. }
  958.  
  959. //----------------------------------------------------------------------------------------
  960. //    CDrawSelection::GetLinkDestination - override
  961. //----------------------------------------------------------------------------------------
  962.  
  963. FW_CLinkDestination* CDrawSelection::GetLinkDestination(Environment* ev, FW_Boolean& multipleLinks)
  964. {
  965. FW_UNUSED(ev);
  966.     // check whether any of the selected shapes is in a link destination
  967.     FW_CLinkDestination* linkDest = NULL;
  968.     multipleLinks = false;
  969.  
  970.     CDrawContentShapeIterator iter(fSelectionContent);
  971.     for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  972.     {
  973.         if (shape->IsSubscribed())
  974.         {
  975.             if (linkDest == NULL)
  976.                 linkDest = shape->GetSubscribeLink();        // return the link destination
  977.             else if (shape->GetSubscribeLink() != linkDest)
  978.             {
  979.                 multipleLinks = true;
  980.                 return NULL;
  981.             }
  982.         }
  983.     }
  984.  
  985.     return linkDest;
  986. }
  987.  
  988. //----------------------------------------------------------------------------------------
  989. //    CDrawSelection::GetSelectionPenSize
  990. //----------------------------------------------------------------------------------------
  991.  
  992. FW_Boolean CDrawSelection::GetSelectionPenSize(Environment* ev, FW_Fixed& penSize)
  993. {
  994. FW_UNUSED(ev);
  995.     CDrawContentShapeIterator iter(fSelectionContent);
  996.     FW_Boolean first = TRUE;
  997.     for (CBaseShape *shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  998.     {
  999.         if (first)
  1000.         {
  1001.             penSize = shape->GetPenSize();
  1002.             first = FALSE;
  1003.         }
  1004.         else
  1005.         {
  1006.             if (shape->GetPenSize() != penSize)
  1007.                 return FALSE;
  1008.         }
  1009.     }
  1010.     
  1011.     return TRUE;
  1012. }
  1013.  
  1014. //----------------------------------------------------------------------------------------
  1015. //    CDrawSelection::SelectContent
  1016. //----------------------------------------------------------------------------------------
  1017. void CDrawSelection::SelectContent(Environment* ev, CDrawContent* content)
  1018. {
  1019.     this->CloseSelection(ev);
  1020.  
  1021.     CDrawContentShapeIterator it(content);
  1022.     for (CBaseShape* shape = it.First(); it.IsNotComplete(); shape = it.Next())
  1023.     {
  1024.         this->AddToSelection(ev, shape, TRUE);
  1025.     }
  1026. }
  1027.  
  1028. //----------------------------------------------------------------------------------------
  1029. //    CDrawSelection::GetDrawContent
  1030. //----------------------------------------------------------------------------------------
  1031. CDrawContent* CDrawSelection::GetDrawContent(Environment*)
  1032. {
  1033.     return fSelectionContent;
  1034. }
  1035.  
  1036. //----------------------------------------------------------------------------------------
  1037. //    CDrawSelection::GetSelectedLinkSources
  1038. //----------------------------------------------------------------------------------------
  1039. CDrawPublishLinkCollection* CDrawSelection::GetSelectedLinkSources()
  1040. {
  1041.     CDrawPublishLinkCollection* sources = NULL;
  1042.     
  1043.     CDrawContentShapeIterator ite(fSelectionContent);
  1044.     for (CBaseShape *shape = ite.First(); ite.IsNotComplete(); shape = ite.Next())
  1045.     {
  1046.         if (shape->IsPublished())
  1047.         {
  1048.             if (sources == NULL)
  1049.                 sources = FW_NEW(CDrawPublishLinkCollection,());
  1050.                 
  1051.             if (!sources->Contains(shape->GetPublishLink()))
  1052.                 sources->AddLast(shape->GetPublishLink());
  1053.         }
  1054.     }
  1055.     
  1056.     return sources;
  1057. }
  1058.  
  1059. //----------------------------------------------------------------------------------------
  1060. //    CDrawSelection::DoFindLinkSource
  1061. //----------------------------------------------------------------------------------------
  1062. FW_CLinkSource* CDrawSelection::DoFindLinkSource(Environment*)
  1063. {
  1064.     FW_ASSERT(this->Count() != 0);
  1065.     
  1066.     FW_CLinkSource* linkSrc = NULL;
  1067.  
  1068.     CDrawContentShapeIterator iter(fSelectionContent);
  1069.     for (CBaseShape* shape = iter.First(); iter.IsNotComplete(); shape = iter.Next())
  1070.     {
  1071.         CDrawPublishLink* src = shape->GetPublishLink();
  1072.         if (src == NULL)
  1073.             return NULL;
  1074.             
  1075.         if (linkSrc == NULL)
  1076.         {
  1077.             if (src->Count() != this->Count())
  1078.                 return NULL;
  1079.                 
  1080.             linkSrc = src;
  1081.         }
  1082.         else if (linkSrc != src)
  1083.             return NULL;
  1084.     }
  1085.  
  1086.     FW_ASSERT(linkSrc != NULL);
  1087.     return linkSrc;
  1088. }
  1089.  
  1090.  
  1091.